﻿using System;
using System.Xml;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;

namespace InfoJetSoft.Service.Worker
{
	
	class XmlXmlToEditRemoveWorker
	{
		
		public static void  remove(Form form, XmlToEditContext context)
		{
			XmlDocument doc = context.Doc;
			
			XmlNode itemNode = context.ItemNode;
			XmlNode parentNode = itemNode.ParentNode;
			if (parentNode is XmlElement)
			{
				XmlElement parentElement = (XmlElement) parentNode;
				if (itemNode is XmlAttribute)
				{
					XmlAttribute attributeItem = (XmlAttribute) itemNode;
					if (SchemaUtil.canRemoveAttr(form, parentElement, attributeItem))
					{
						//需用在Remove之前计算Path,不能移动.
						string path = DOMUtil.getNodePath( attributeItem );

                        //CID 0907 //2011.05.13 //Begin
                        DeleteContext deleteContext = FormCalculatedFieldWorker.CreateDeleteContext(form, attributeItem);
						parentElement.RemoveAttributeNode(attributeItem);
                        FormCalculatedFieldWorker.calcaulteGroupNode(form, attributeItem, deleteContext, false);
                        //CID 0907 //2011.05.13 //End

						if (context.XmlToEdit.RemoveAncestors > 0 && getXmlToEditItemXmlNodeList(context).Count <= 0)
						{
							doRemoveAncestors(form, parentElement, context.XmlToEdit.RemoveAncestors);
						}

                        FormCodeDispatchWorker.OnAfterChange(form, path, attributeItem, FormCodeDispatchWorker.Updated, false);
					}
					//CID 0109 //2008.09.07 //Begin
					else
					{
						string cannotRemoveMessage = "The item cannot be removed.\nContent for element '" + attributeItem.OwnerElement.LocalName + "' is incomplete according to the DTD/Schema.";
						form.ModalMessageList.Add( cannotRemoveMessage );
					}
					//CID 0109 //2008.09.07 //End
				}
				else if (itemNode is XmlElement)
				{
					XmlElement elementItem = (XmlElement) itemNode;
					if (SchemaUtil.canRemoveChild(form, parentElement, elementItem))
					{
						//需要在Remvoe之前计算Path,不能移动.
						string path = DOMUtil.getNodePath(elementItem);
						//检查是否需要更新MasterDetail上下文。
						//这里是在删除之前更新的，而InsertSection时是插入之前更新的，效果都一样。
						FormMasterDetailContextWorker.updateMasterDetialContext( form, context, elementItem, true );

                        //CID 0907 //2011.05.13 //Begin
                        DeleteContext deleteContext = FormCalculatedFieldWorker.CreateDeleteContext(form, elementItem);
                        parentElement.RemoveChild(elementItem);
                        FormCalculatedFieldWorker.calcaulteGroupNode(form, elementItem, deleteContext, false);
                        //CID 0907 //2011.05.13 //End

						if (context.XmlToEdit.RemoveAncestors > 0 && getXmlToEditItemXmlNodeList(context).Count <= 0)
						{
							doRemoveAncestors(form, parentElement, context.XmlToEdit.RemoveAncestors);
						}

                        //CID 0743 //2010.12.27 //Begin
                        //FormCalculatedFieldWorker.calculateValueNode(form, parentElement);
                        //CID 0743 //2010.12.27 //End
                        FormCodeDispatchWorker.OnAfterChange(form, path, elementItem, FormCodeDispatchWorker.Updated, false);
					}
					//CID 0109 //2008.09.07 //Begin
					else
					{
						string cannotRemoveMessage = "The item cannot be removed.\nContent for element '" + elementItem.ParentNode.LocalName + "' is incomplete according to the DTD/Schema.";
						form.ModalMessageList.Add( cannotRemoveMessage );
					}
					//CID 0109 //2008.09.07 //End
				}
			}
		}
		
		public static void  removeAll(Form form, XmlToEditContext context)
		{
			XmlDocument doc = context.Doc;
			
			XmlNodeList itemXmlNodeList = getXmlToEditItemXmlNodeList(context);
			XmlElement oneParentElement = null;
			
			foreach (XmlNode itemNode in itemXmlNodeList)
			{
				XmlNode parentNode = itemNode.ParentNode;
				if (parentNode is XmlElement)
				{
					XmlElement parentElement = (XmlElement) parentNode;
					if (itemNode is XmlAttribute)
					{
						XmlAttribute attributeItem = (XmlAttribute) itemNode;
						if (SchemaUtil.canRemoveAttr(form, parentElement, attributeItem))
						{
                            //CID 0907 //2011.05.13 //Begin
                            DeleteContext deleteContext = FormCalculatedFieldWorker.CreateDeleteContext(form, attributeItem);
                            parentElement.RemoveAttributeNode(attributeItem);
                            FormCalculatedFieldWorker.calcaulteGroupNode(form, attributeItem, deleteContext, false);
                            //CID 0907 //2011.05.13 //End

							oneParentElement = parentElement;
						}
					}
					else if (itemNode is XmlElement)
					{
						XmlElement elementItem = (XmlElement) itemNode;
						if (SchemaUtil.canRemoveChild(form, parentElement, elementItem))
						{
                            //CID 0907 //2011.05.13 //Begin
                            DeleteContext deleteContext = FormCalculatedFieldWorker.CreateDeleteContext(form, elementItem);
                            parentElement.RemoveChild(elementItem);
                            FormCalculatedFieldWorker.calcaulteGroupNode(form, elementItem, deleteContext, false);
                            //CID 0907 //2011.05.13 //End

							oneParentElement = parentElement;
						}
					}
				}
			}
			
			if (oneParentElement != null)
			{
                //CID 0907 //DeleteContext
				doRemoveAncestors(form, oneParentElement, context.XmlToEdit.RemoveAncestors);
			}
		}
		
		private static XmlNodeList getXmlToEditItemXmlNodeList(XmlToEditContext context)
		{
			XmlToEdit xmlToEdit = context.XmlToEdit;
			XmlDocument doc = context.Doc;
			XmlNodeList itemXmlNodeList = DOMUtil.selectNodes(doc, xmlToEdit.Item, 0, context.NsResolver);
			return itemXmlNodeList;
		}
		
		private static void  doRemoveAncestors(Form form, XmlElement parentElement, int removeAncestors)
		{
			if (removeAncestors <= 0)
			{
				return ;
			}
			
			XmlElement ancestorElement = parentElement;
			for (int i = 0; i < removeAncestors - 1; i++)
			{
				if (parentElement.ParentNode is XmlElement)
				{
					ancestorElement = (XmlElement) parentElement.ParentNode;
					if (ancestorElement == null)
					{
						return ;
					}
				}
				else
				{
					return ;
				}
			}
			
			if (ancestorElement.ParentNode is XmlElement)
			{
				XmlElement ancestorParentElement = (XmlElement) ancestorElement.ParentNode;
				if (ancestorParentElement != null)
				{
					if (SchemaUtil.canRemoveChild(form, ancestorParentElement, ancestorElement))
					{
                        //CID 0907 //2011.05.13 //Begin
                        DeleteContext deleteContext = FormCalculatedFieldWorker.CreateDeleteContext(form, ancestorElement);
						ancestorParentElement.RemoveChild(ancestorElement);
                        FormCalculatedFieldWorker.calcaulteGroupNode(form, ancestorElement, deleteContext, true);
                        //CID 0907 //2011.05.13 //End
					}
				}
			}
		}
	}
}